Take-home Exercise 2: Spatial Point Patterns Analysis of Airbnb Listing in Singapore

This exercise aims to investigate if the distribution of Airbnb listings in Singapore are affected by location factors and COVID-19.

Niharika Avula https://example.com/norajones
2021-10-02

1.0 OVERVIEW

1.1 ABOUT AIRBNB

Airbnb is primarily an online accommodation rental marketplace which enables hosts to rent out their properties or rooms to guests. It has also expanded to offer “experiences” which the company describes as “unique activities we can do together, led by a world of hosts”. Since its inception in 2008, Airbnb has expanded into over 34,000 cities across 191 countries and opened its first international office in Hamburg, Germany in 2011. Though the company began as a privately owned business, it went public in 2020 at the beginning stages of COVID-19 pandemic.

Airbnb does not actually own the properties it offers for rent on its website, but rather generates its revenue through service fees to hosts and guests. In 2019, Airbnb was valued at 35 billion U.S. dollars. While SIngapore was their first choice to agrgresively expand in Asian markets, interestingly, Singapore is one of the global cities that has yet to legalise short-term rentals offered by Airbnb. Nonetheless, it will be interesting to see how Airbnb is faring in Singapore, especially given the recent COVID-19.

1.2 PROBLEM STATEMENT

This exercise aims to investigate if the distribution of Airbnb listings in Singapore are affected by location factors and COVID-19. Therefore, my analysis is split into two parts aiming to answer the following two questions:

2.0 GETTING STARTED

This section covers installing the applicable R packages as well as importing the necessary data for analysis

2.1 SETTING UP THE ENVIRONMENT

The following R packages will be used in this analysis:

packages <- c('maptools', 'sf', 'raster', 'spatstat', 'tmap', 'tidyverse', 'plotly', 'ggthemes')

for (p in packages){
  if (!require(p, character.only = T)){
    install.packages(p)
  }
  library(p, character.only = T)
  }

2.2 IMPORTING DATA

The table below shows all the data that will be imported for this analysis

Data Type Name Source
Geospatial Master Plan 2014 Subzone Boundary (Web) link
Geospatial MRT & LRT Locations Aug 2021 link
Geospatial Singapore National Boundary link
Aspatial Singapore Airbnb Listings June 2019 link
Aspatial Singapore Airbnb Listings July 2021 link
Aspatial Tourism OneMap
Aspatial Hotels OneMap

DATA TALKING POINTS:

2.2.1 IMPORTING GEOSPATIAL DATA

mpsz_sf <- st_read(dsn = "data/geospatial", 
                   layer = "MP14_SUBZONE_WEB_PL")
Reading layer `MP14_SUBZONE_WEB_PL' from data source 
  `C:\Niharika-avula\IS415_blog\_posts\Take Home Exercise-2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 323 features and 15 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2667.538 ymin: 15748.72 xmax: 56396.44 ymax: 50256.33
Projected CRS: SVY21
MRT_LRT_Network_sf <- st_read(dsn = "data/geospatial", 
                   layer = "MRTLRTStnPtt")
Reading layer `MRTLRTStnPtt' from data source 
  `C:\Niharika-avula\IS415_blog\_posts\Take Home Exercise-2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 171 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 6138.311 ymin: 27555.06 xmax: 45254.86 ymax: 47854.2
Projected CRS: SVY21
sg_sf <- st_read(dsn = "data/geospatial", layer="CostalOutline")
Reading layer `CostalOutline' from data source 
  `C:\Niharika-avula\IS415_blog\_posts\Take Home Exercise-2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 60 features and 4 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 2663.926 ymin: 16357.98 xmax: 56047.79 ymax: 50244.03
Projected CRS: SVY21

2.2.2 IMPORTING ASPATIAL DATA

Listings_2019 <- read_csv("data/aspatial/listings_30062019.csv", show_col_types=FALSE)
Listings_2021 <- read_csv("data/aspatial/listings_19072021.csv", show_col_types=FALSE)
Hotels <- read_csv("data/aspatial/hotels.csv", show_col_types=FALSE)
Tourism <- read_csv("data/aspatial/tourism.csv", show_col_types=FALSE)

We have come to end of Section 2 with R packages installed and the Geospatial and Aspatial data imported, next section will cover data wrangling process of the imported data Verifying the project CRS of the above imported data

3.0 GEOSPATIAL DATA WRANGLING

This section covers all the steps taken in the pre-processing of the mpsz_sf and MRT_LRT_Network_sf data, which includes the following steps:

Took reference from senior’s project given as sample for this section

3.1 VERIFYING & TRANSFORMING CRS

MPSZ_SF

st_crs(mpsz_sf) 
Coordinate Reference System:
  User input: SVY21 
  wkt:
PROJCRS["SVY21",
    BASEGEOGCRS["SVY21[WGS84]",
        DATUM["World Geodetic System 1984",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]],
            ID["EPSG",6326]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["Degree",0.0174532925199433]]],
    CONVERSION["unnamed",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]

MRT_LRT_NETWORK_SF

st_crs(MRT_LRT_Network_sf) 
Coordinate Reference System:
  User input: SVY21 
  wkt:
PROJCRS["SVY21",
    BASEGEOGCRS["SVY21[WGS84]",
        DATUM["World Geodetic System 1984",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]],
            ID["EPSG",6326]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["Degree",0.0174532925199433]]],
    CONVERSION["unnamed",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]

SG_SF

st_crs(sg_sf) 
Coordinate Reference System:
  User input: SVY21 
  wkt:
PROJCRS["SVY21",
    BASEGEOGCRS["SVY21[WGS84]",
        DATUM["World Geodetic System 1984",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]],
            ID["EPSG",6326]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["Degree",0.0174532925199433]]],
    CONVERSION["unnamed",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]

It can be seen that while the projected CRS is SVY21, the current EPSG Code is 9001, hence the next step is to assign the correct 3414 EPSG code

MPSZ_SF

mpsz_sf <- st_set_crs(mpsz_sf, 3414)
st_crs(mpsz_sf) 
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]

MRT_LRT_NETWORK_SF

MRT_LRT_Network_sf <- st_set_crs(MRT_LRT_Network_sf, 3414)
st_crs(MRT_LRT_Network_sf) 
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]

SG_SF

sg_sf <- st_set_crs(sg_sf, 3414)
st_crs(sg_sf) 
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]

The correct projected CRS with EPSG Code 3413 is assigned and now we can move on to the next step

3.2 HANDLING MISSING VALUES

Checking for missing values as they can impact future calculations and visualisations.

MPSZ_SF

mpsz_sf[rowSums(is.na(mpsz_sf))!=0,]
Simple feature collection with 0 features and 15 fields
Bounding box:  xmin: NA ymin: NA xmax: NA ymax: NA
Projected CRS: SVY21 / Singapore TM
 [1] OBJECTID   SUBZONE_NO SUBZONE_N  SUBZONE_C  CA_IND     PLN_AREA_N
 [7] PLN_AREA_C REGION_N   REGION_C   INC_CRC    FMEL_UPD_D X_ADDR    
[13] Y_ADDR     SHAPE_Leng SHAPE_Area geometry  
<0 rows> (or 0-length row.names)

MRT_LRT_NETWORK_SF

MRT_LRT_Network_sf[rowSums(is.na(MRT_LRT_Network_sf))!=0,]
Simple feature collection with 0 features and 3 fields
Bounding box:  xmin: NA ymin: NA xmax: NA ymax: NA
Projected CRS: SVY21 / Singapore TM
[1] OBJECTID STN_NAME STN_NO   geometry
<0 rows> (or 0-length row.names)

SG_SF

sg_sf[rowSums(is.na(sg_sf))!=0,]
Simple feature collection with 0 features and 4 fields
Bounding box:  xmin: NA ymin: NA xmax: NA ymax: NA
Projected CRS: SVY21 / Singapore TM
[1] GDO_GID    MSLINK     MAPID      COSTAL_NAM geometry  
<0 rows> (or 0-length row.names)

There are no missing values in both mpsz_sf and MRT_LRT_Network_sf data

3.3 HANDLING INVALID GEOMETRIES

Checking for invalid geometries as they can impact future calculations and visualisations.

MPSZ_SF

length(which(st_is_valid(mpsz_sf) == FALSE))
[1] 9

MRT_LRT_NETWORK_SF

length(which(st_is_valid(MRT_LRT_Network_sf) == FALSE))
[1] 0

SG_SF

length(which(st_is_valid(sg_sf) == FALSE))
[1] 1

It can be seen that there are 9 invalid geometries in the mpsz_sf data and 1 invalid geometry in sg_sf data while there are no invalid geometries in MRT_LRT_Network_sf data, hence the invalid geometries need to be made valid

MPSZ_SF

mpsz_sf <- st_make_valid(mpsz_sf)
length(which(st_is_valid(mpsz_sf) == FALSE))
[1] 0

SG_SF

sg_sf <- st_make_valid(sg_sf)
length(which(st_is_valid(sg_sf) == FALSE))
[1] 0

Invalid geometries have been handled, there are no more invalid geometries in both datasets.

VISUALISING GEOSPATIAL DATA

Before we jump into the analysis, it is a good practice to visualise the geospatial data

MPSZ

plot(st_geometry(mpsz_sf))

SG_SF

plot(st_geometry(sg_sf))

MRT_LRT_NETWORK

tmap_mode("view")
tm_shape(mpsz_sf) +
  tm_borders(alpha = 0.5) +
  tmap_options(check.and.fix = TRUE) +
  
tm_shape(MRT_LRT_Network_sf) +
  tm_dots(col = 'red', size = 0.02)
tmap_mode("plot")

With that, we have come to end of section 3 with the pre-processing of geospatial mpsz_sf and MRT_LRT_Network_sf data completed, next section will be looking into the same process for Aspatial data.

4.0 ASPATIAL DATA WRANGLING

This section covers all the steps taken in the pre-processing of the Listings_2019, Listings_2021, Hotels and Tourism data, which includes the following steps:

Let’s have a glimpse at the data first

glimpse(Listings_2019)
Rows: 8,293
Columns: 16
$ id                             <dbl> 49091, 50646, 56334, 71609, 7~
$ name                           <chr> "COZICOMFORT LONG TERM STAY R~
$ host_id                        <dbl> 266763, 227796, 266763, 36704~
$ host_name                      <chr> "Francesca", "Sujatha", "Fran~
$ neighbourhood_group            <chr> "North Region", "Central Regi~
$ neighbourhood                  <chr> "Woodlands", "Bukit Timah", "~
$ latitude                       <dbl> 1.44255, 1.33235, 1.44246, 1.~
$ longitude                      <dbl> 103.7958, 103.7852, 103.7967,~
$ room_type                      <chr> "Private room", "Private room~
$ price                          <dbl> 81, 80, 68, 200, 92, 102, 203~
$ minimum_nights                 <dbl> 180, 90, 6, 1, 1, 1, 1, 7, 30~
$ number_of_reviews              <dbl> 1, 18, 20, 12, 20, 35, 23, 15~
$ last_review                    <date> 2013-10-21, 2014-12-26, 2015~
$ reviews_per_month              <dbl> 0.01, 0.28, 0.21, 0.13, 0.21,~
$ calculated_host_listings_count <dbl> 2, 1, 2, 9, 9, 9, 9, 1, 4, 4,~
$ availability_365               <dbl> 365, 365, 365, 353, 353, 348,~

Listings_2019 has latitude and longitude features

glimpse(Listings_2021)
Rows: 4,252
Columns: 18
$ id                             <dbl> 50646, 71609, 71896, 71903, 2~
$ name                           <chr> "Pleasant Room along Bukit Ti~
$ host_id                        <dbl> 227796, 367042, 367042, 36704~
$ host_name                      <chr> "Sujatha", "Belinda", "Belind~
$ neighbourhood_group            <chr> "Central Region", "East Regio~
$ neighbourhood                  <chr> "Bukit Timah", "Tampines", "T~
$ latitude                       <dbl> 1.33432, 1.34537, 1.34754, 1.~
$ longitude                      <dbl> 103.7852, 103.9589, 103.9596,~
$ room_type                      <chr> "Private room", "Private room~
$ price                          <dbl> 80, 178, 81, 81, 52, 40, 72, ~
$ minimum_nights                 <dbl> 90, 90, 90, 90, 14, 14, 90, 8~
$ number_of_reviews              <dbl> 18, 20, 24, 48, 20, 13, 133, ~
$ last_review                    <date> 2014-07-08, 2019-12-28, 2014~
$ reviews_per_month              <dbl> 0.22, 0.28, 0.33, 0.67, 0.20,~
$ calculated_host_listings_count <dbl> 1, 4, 4, 4, 50, 50, 7, 1, 50,~
$ availability_365               <dbl> 365, 365, 365, 365, 353, 364,~
$ number_of_reviews_ltm          <dbl> 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,~
$ license                        <chr> NA, NA, NA, NA, NA, NA, NA, N~

Listings_2021 has latitude and longitude features

glimpse(Hotels)
Rows: 422
Columns: 9
$ NAME              <chr> "Jayleen Clarke Quay Hotel", "JEN Singapor~
$ ADDRESSPOSTALCODE <dbl> 59390, 238858, 249716, 399041, 238485, 399~
$ ADDRESSSTREETNAME <chr> "25 New Bridge Road", "277 Orchard Road , ~
$ HYPERLINK         <chr> "jayleenclarkequay@gmail.com", "singaporeo~
$ TOTALROOMS        <dbl> 20, 499, 565, 42, 81, 33, 17, 634, 56, 451~
$ KEEPERNAME        <chr> "James Federick Chong Kah Yean", "Kuok Oon~
$ Lat               <dbl> 1.288715, 1.300510, 1.304271, 1.311586, 1.~
$ Lng               <dbl> 103.8475, 103.8392, 103.8239, 103.8775, 10~
$ ICON_NAME         <chr> "hotel.gif", "hotel.gif", "hotel.gif", "ho~

Hotels has Lat and Lng features

glimpse(Tourism)
Rows: 107
Columns: 17
$ NAME              <chr> "Chinatown Heritage Centre, Singapore", "T~
$ DESCRIPTION       <chr> "Experience how Singapore’s early Chinese ~
$ ADDRESSSTREETNAME <chr> "48 Pagoda Street", "158 Telok Ayer Street~
$ HYPERLINK         <chr> "http://www.singaporechinatown.com.sg/", "~
$ PHOTOURL          <chr> "www.yoursingapore.com/content/dam/desktop~
$ URL_PATH          <chr> "www.yoursingapore.com/en/see-do-singapore~
$ IMAGE_ALT_TEXT    <chr> "Learn more about local Chinese culture at~
$ PHOTOCREDITS      <chr> "Joel Chua DY", "Joel Chua DY", "Joel Chua~
$ LASTMODIFIED      <dttm> 2015-11-02 02:16:52, 2015-11-02 02:20:57,~
$ LATITUDE          <dbl> 1.283510, 1.280940, 1.310070, 1.277219, 1.~
$ LONGTITUDE        <dbl> 103.8444, 103.8476, 103.8994, 103.8373, 10~
$ META_DESCRIPTION  <chr> "At the Chinatown Heritage Centre, experie~
$ OPENING_HOURS     <chr> "Daily, 9am – 8pm,Last entry at 7pm.*China~
$ Lat               <dbl> 1.283510, 1.280940, 1.310070, 1.277219, 1.~
$ Lng               <dbl> 103.8444, 103.8476, 103.8994, 103.8373, 10~
$ ICON_NAME         <chr> "tourist_spot.gif", "tourist_spot.gif", "t~
$ ADDRESSPOSTALCODE <dbl> NA, NA, NA, 0, NA, NA, NA, NA, NA, NA, NA,~

Tourism has both Lat and Lng and latitude and longitude features, this needs to be further explored to check if there are missing values

4.1 HANDLING MISSING VALUES

LISTINGS_2019 DATA

sum(is.na(Listings_2019$longitude))
[1] 0
sum(is.na(Listings_2019$latitude))
[1] 0

No Missing values in the latitude and longitude columns in Listing_2019 data

LISTINGS_2021 DATA

sum(is.na(Listings_2021$longitude))
[1] 0
sum(is.na(Listings_2021$latitude))
[1] 0

No Missing values in the latitude and longitude columns in Listing_2021 data

HOTELS DATA

sum(is.na(Hotels$Lng))
[1] 0
sum(is.na(Hotels$Lat))
[1] 0

No Missing values in the Lng and Lat columns in Hotels data

TOURISM DATA

sum(is.na(Tourism$Lng))
[1] 0
sum(is.na(Tourism$Lat))
[1] 0

No Missing values in the Lng and Lat columns in Tourism data

sum(is.na(Tourism$LATITUDE))
[1] 1
sum(is.na(Tourism$LONGTITUDE))
[1] 1

It can be seen that there is one missing values in the Longitude and Latitude columns in Tourism data, hence will be using the Lat and Lng for Tourism data.

In order to identify the tourist attraction with the missing values

Tourism[(is.na(Tourism$LONGTITUDE)),]
# A tibble: 1 x 17
  NAME   DESCRIPTION   ADDRESSSTREETNAME HYPERLINK PHOTOURL  URL_PATH 
  <chr>  <chr>         <chr>             <chr>     <chr>     <chr>    
1 Cruis~ Watch the Si~ <NA>              <NA>      www.your~ www.your~
# ... with 11 more variables: IMAGE_ALT_TEXT <chr>,
#   PHOTOCREDITS <chr>, LASTMODIFIED <dttm>, LATITUDE <dbl>,
#   LONGTITUDE <dbl>, META_DESCRIPTION <chr>, OPENING_HOURS <chr>,
#   Lat <dbl>, Lng <dbl>, ICON_NAME <chr>, ADDRESSPOSTALCODE <dbl>
Tourism[(is.na(Tourism$LATITUDE)),]
# A tibble: 1 x 17
  NAME   DESCRIPTION   ADDRESSSTREETNAME HYPERLINK PHOTOURL  URL_PATH 
  <chr>  <chr>         <chr>             <chr>     <chr>     <chr>    
1 Cruis~ Watch the Si~ <NA>              <NA>      www.your~ www.your~
# ... with 11 more variables: IMAGE_ALT_TEXT <chr>,
#   PHOTOCREDITS <chr>, LASTMODIFIED <dttm>, LATITUDE <dbl>,
#   LONGTITUDE <dbl>, META_DESCRIPTION <chr>, OPENING_HOURS <chr>,
#   Lat <dbl>, Lng <dbl>, ICON_NAME <chr>, ADDRESSPOSTALCODE <dbl>

The tourist attraction with missing value happens to be cruise. As we are looking into Airbnb listings, I suppose it will not matter a lot whether they are close to cruise or not, hence going to remove cruise form the dataset.

Tourism <- Tourism[!(is.na(Tourism$LONGTITUDE)), ]
Tourism <- Tourism[!(is.na(Tourism$LATITUDE)), ]
glimpse(Tourism)
Rows: 106
Columns: 17
$ NAME              <chr> "Chinatown Heritage Centre, Singapore", "T~
$ DESCRIPTION       <chr> "Experience how Singapore’s early Chinese ~
$ ADDRESSSTREETNAME <chr> "48 Pagoda Street", "158 Telok Ayer Street~
$ HYPERLINK         <chr> "http://www.singaporechinatown.com.sg/", "~
$ PHOTOURL          <chr> "www.yoursingapore.com/content/dam/desktop~
$ URL_PATH          <chr> "www.yoursingapore.com/en/see-do-singapore~
$ IMAGE_ALT_TEXT    <chr> "Learn more about local Chinese culture at~
$ PHOTOCREDITS      <chr> "Joel Chua DY", "Joel Chua DY", "Joel Chua~
$ LASTMODIFIED      <dttm> 2015-11-02 02:16:52, 2015-11-02 02:20:57,~
$ LATITUDE          <dbl> 1.283510, 1.280940, 1.310070, 1.277219, 1.~
$ LONGTITUDE        <dbl> 103.8444, 103.8476, 103.8994, 103.8373, 10~
$ META_DESCRIPTION  <chr> "At the Chinatown Heritage Centre, experie~
$ OPENING_HOURS     <chr> "Daily, 9am – 8pm,Last entry at 7pm.*China~
$ Lat               <dbl> 1.283510, 1.280940, 1.310070, 1.277219, 1.~
$ Lng               <dbl> 103.8444, 103.8476, 103.8994, 103.8373, 10~
$ ICON_NAME         <chr> "tourist_spot.gif", "tourist_spot.gif", "t~
$ ADDRESSPOSTALCODE <dbl> NA, NA, NA, 0, NA, NA, NA, NA, NA, NA, NA,~

Therefore, the number rows decreased from 107 to 106 in the Tourism dataset

4.2 CONVERTING INTO SF OBJECTS & TRANSFORMING CRS

This converts the below dataframes into sf objects and transform the projected CRS to 3414

Listings_2019_sf <- st_as_sf(Listings_2019, 
                    coords = c("longitude",
                               "latitude"),
                    crs = 4326) %>%
   st_transform(crs=3414)

Listings_2021_sf <- st_as_sf(Listings_2021, 
                    coords = c("longitude",
                               "latitude"),
                    crs = 4326) %>%
   st_transform(crs=3414)

Hotels_sf <- st_as_sf(Hotels, 
                    coords = c("Lng",
                               "Lat"),
                    crs = 4326) %>%
   st_transform(crs=3414)

Tourism_sf <- st_as_sf(Tourism, 
                    coords = c("Lng",
                               "Lat"),
                    crs = 4326) %>%
   st_transform(crs=3414)

Checking if the correct CRS and EPSG code is assigned

LISTINGS_2019_SF

st_crs(Listings_2019_sf)
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]

LISTINGS_2021_SF

st_crs(Listings_2021_sf)
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]
HOTELS_SF
st_crs(Hotels_sf)
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]

TOURISM_SF

st_crs(Tourism_sf)
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]

We have come to end of section 4 with the pre-processing of aspatial Listings_2019, Listings_2021, Hotels and Tourism data completed

5.0 COMBINING GEOSPATIAL & ASPATIAL DATA

This section covers the steps taken to convert both the geospatial and aspatial data into the appropriate formats for performing spatial point pattern analysis.

Geospatial: mpsz_sf, sg_sf, and MRT_LRT_Network_sf

Aspatial: Listings_2019_sf, Listings_2021_sf, Hotels_sf and Tourism_sf

5.1 CONVERTING SF DATA FRAME TO SP’S SPATIAL* CLASS

With the below code chunk, all of the above geospatial and aspatial data frames are converted into sp’s Spatial* class

mpsz <- as_Spatial(mpsz_sf)
MRT_LRT_Network <-as_Spatial(MRT_LRT_Network_sf)
sg <- as_Spatial(sg_sf)
Listings_2019 <- as_Spatial(Listings_2019_sf)
Listings_2021 <- as_Spatial(Listings_2021_sf)
Hotels <- as_Spatial(Hotels_sf)
Tourism <- as_Spatial(Tourism_sf)

Checking if the conversion is successful

MPSZ

mpsz
class       : SpatialPolygonsDataFrame 
features    : 323 
extent      : 2667.538, 56396.44, 15748.72, 50256.33  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 15
names       : OBJECTID, SUBZONE_NO, SUBZONE_N, SUBZONE_C, CA_IND, PLN_AREA_N, PLN_AREA_C,       REGION_N, REGION_C,          INC_CRC, FMEL_UPD_D,     X_ADDR,     Y_ADDR,    SHAPE_Leng,    SHAPE_Area 
min values  :        1,          1, ADMIRALTY,    AMSZ01,      N, ANG MO KIO,         AM, CENTRAL REGION,       CR, 00F5E30B5C9B7AD8,      16409,  5092.8949,  19579.069, 871.554887798, 39437.9352703 
max values  :      323,         17,    YUNNAN,    YSSZ09,      Y,     YISHUN,         YS,    WEST REGION,       WR, FFCCF172717C2EAF,      16409, 50424.7923, 49552.7904, 68083.9364708,  69748298.792 

MRT_LRT_NETWORK

MRT_LRT_Network
class       : SpatialPointsDataFrame 
features    : 171 
extent      : 6138.311, 45254.86, 27555.06, 47854.2  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 3
names       : OBJECTID,              STN_NAME, STN_NO 
min values  :        1, ADMIRALTY MRT STATION,    BP1 
max values  :      199,    YISHUN MRT STATION,    TE8 

SG

sg
class       : SpatialPolygonsDataFrame 
features    : 60 
extent      : 2663.926, 56047.79, 16357.98, 50244.03  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 4
names       : GDO_GID, MSLINK, MAPID,              COSTAL_NAM 
min values  :       1,      1,     0,             ISLAND LINK 
max values  :      60,     67,     0, SINGAPORE - MAIN ISLAND 

LISTINGS_2019

Listings_2019
class       : SpatialPointsDataFrame 
features    : 8293 
extent      : 7215.566, 44098.31, 25166.35, 49226.35  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 14
names       :       id,                                              name,   host_id,                host_name, neighbourhood_group, neighbourhood,       room_type, price, minimum_nights, number_of_reviews, last_review, reviews_per_month, calculated_host_listings_count, availability_365 
min values  :    49091,                                                 -,     23666, (Email hidden by Airbnb),      Central Region,    Ang Mo Kio, Entire home/apt,     0,              1,                 0,       15656,              0.01,                              1,                0 
max values  : 36053005, ZR2- NEW! Sunny & Modern Apt 4 mins to Orchard Rd, 271165196,                   Zuzana,         West Region,        Yishun,     Shared room, 13999,           1000,               308,       18072,             12.09,                            277,              365 

LISTINGS_2021

Listings_2021
class       : SpatialPointsDataFrame 
features    : 4252 
extent      : 7406.989, 43337.89, 25330, 48391.55  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 16
names       :       id,                                               name,   host_id,        host_name, neighbourhood_group, neighbourhood,       room_type, price, minimum_nights, number_of_reviews, last_review, reviews_per_month, calculated_host_listings_count, availability_365, number_of_reviews_ltm, ... 
min values  :    50646, !! CozyRoom@City Center,Little India,FarrerParkMRT,     23666, <U+4F73><U+4F73>,      Central Region,    Ang Mo Kio, Entire home/apt,    13,              1,                 0,       15456,              0.01,                              1,                0,                     0, ... 
max values  : 51122424,                 Zimmer nah der MRT (Downtown Line), 411376818,             Zuzu,         West Region,        Yishun,     Shared room, 13400,           1000,               370,       18826,                77,                            165,              365,                   195, ... 

HOTELS

Hotels
class       : SpatialPointsDataFrame 
features    : 422 
extent      : 5939.241, 45334.18, 25379.44, 44562.4  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 7
names       :                              NAME, ADDRESSPOSTALCODE,                                 ADDRESSSTREETNAME,         HYPERLINK, TOTALROOMS,     KEEPERNAME, ICON_NAME 
min values  :                      30 BENCOOLEN,             18956,                                 1 Bayfront Avenue, 96ytlim@gmail.com,          4,  Adel Aramouni, hotel.gif 
max values  : YotelAir Singapore Changi Airport,            819666, 99 IRRAWADDY ROAD, # 22-00 ROYAL SQUARE AT NOVENA, zubair@dam.com.sg,       2561, Zhang YuanQing, hotel.gif 

TOURISM

Tourism
class       : SpatialPointsDataFrame 
features    : 106 
extent      : 11380.23, 43659.54, 22869.34, 47596.73  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 15
names       :                                NAME,                                                                                                                                                  DESCRIPTION,                  ADDRESSSTREETNAME,                            HYPERLINK,                                                                                                                             PHOTOURL,                                                                                          URL_PATH,                                                                                                          IMAGE_ALT_TEXT,                 PHOTOCREDITS,   LASTMODIFIED,  LATITUDE, LONGTITUDE,                                                                                             META_DESCRIPTION,                                                                                                                                                                           OPENING_HOURS,        ICON_NAME, ADDRESSPOSTALCODE 
min values  : Adventure Cove Waterpark™ Singapore, A feat of engineering, an architectural statement and a sheer aesthetic triumph, Marina Bay Sands<sup>®</sup> has upped the ante for buildings in Singapore.,                       1 Beach Road,                   http://acm.org.sg/,                                  /content/dam/desktop/global/see-do-singapore/architecture/hajjah-fatimah-mosque-carousel01-rect.jpg, www.yoursingapore.com/en/see-do-singapore/architecture/historical/capitol-building-singapore.html,               Adults and kids of all ages who are not even science buffs will have fun at the Singapore Science Centre., ©Darren Soh/National Gallery, 1427691447.648, 1.2230965,  103.68398, A tranquil patch of imperial China in the west of Singapore is pleasant respite from the bustle of the city.,                                                                                                                                                 50th storey Skybridge, Daily, 9am –10pm, tourist_spot.gif,                 0 
max values  :          Victoria Theatre Singapore,                                                    With so many attractions packed into this 15-km stretch of beaches, you’ll never run out of things to do., Seng Poh Road and Tiong Bahru Road, https://www.pub.gov.sg/marinabarrage, www.yoursingapore.com/content/dam/desktop/global/see-do-singapore/recreation-leisure/universal-studios-singapore-carousel01-rect.jpg,      www.yoursingapore.com/en/see-do-singapore/recreation-leisure/viewpoints/singapore-flyer.html, Whether you prefer water sports, rollerblading or cycling, find a myriad of things to do at East Coast Park, Singapore.,  Wildlife Reserves Singapore, 1446544541.364,   1.44672,  103.97403,                                     With the Henderson Waves bridge, form meets function to stunning effect., Visits are by appointment only.Visitors must sign up in advance for heritage tours which fall on:Monday, 2pm – 3pm,Tuesday, 6.30pm – 7.30pm,Thursday, 10am – 11am,Saturday, 11am – 12pm, tourist_spot.gif,                 0 

All of the above data have been converted into their respective sp’s Spatial * classes

5.2 CONVERTING THE SPATIAL* CLASS INTO GENERIC SP FORMAT

This section covers the steps taken to convert Spatial* classes into Spatial objects

mpsz_sp <- as(mpsz, "SpatialPolygons")
sg_sp <- as(sg, "SpatialPolygons")
MRT_LRT_Network_sp <-as(MRT_LRT_Network, "SpatialPoints")
Listings_2019_sp <- as(Listings_2019, "SpatialPoints")
Listings_2021_sp <- as(Listings_2021, "SpatialPoints")
Hotels_sp <- as(Hotels, "SpatialPoints")
Tourism_sp <- as(Tourism, "SpatialPoints")

Checking if the conversion is successful

MPSZ_SP

mpsz_sp
class       : SpatialPolygons 
features    : 323 
extent      : 2667.538, 56396.44, 15748.72, 50256.33  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 

SG_SP

sg_sp
class       : SpatialPolygons 
features    : 60 
extent      : 2663.926, 56047.79, 16357.98, 50244.03  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 

MRT_LRT_NETWORK_SP

MRT_LRT_Network_sp
class       : SpatialPoints 
features    : 171 
extent      : 6138.311, 45254.86, 27555.06, 47854.2  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 

LISTINGS_2019_SP

Listings_2019_sp
class       : SpatialPoints 
features    : 8293 
extent      : 7215.566, 44098.31, 25166.35, 49226.35  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 

LISTINGS_2021_SP

Listings_2021_sp
class       : SpatialPoints 
features    : 4252 
extent      : 7406.989, 43337.89, 25330, 48391.55  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 

HOTELS_SP

Hotels_sp
class       : SpatialPoints 
features    : 422 
extent      : 5939.241, 45334.18, 25379.44, 44562.4  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 

TOURISM_SP

Tourism_sp
class       : SpatialPoints 
features    : 106 
extent      : 11380.23, 43659.54, 22869.34, 47596.73  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 

All of the above data have been converted successfully

5.3 CONVERTING THE GENERIC SP FORMAT INTO SPATSTAT’S PPP FORMAT

This section covers the steps taken to convert Spatial data into spatista’s ppp objects

MRT_LRT_Network_ppp <-as(MRT_LRT_Network_sp, "ppp")
Listings_2019_ppp <- as(Listings_2019_sp, "ppp")
Listings_2021_ppp <- as(Listings_2021_sp, "ppp")
Hotels_ppp <- as(Hotels_sp, "ppp")
Tourism_ppp <- as(Tourism_sp, "ppp")

Checking the summary statistics of the newly created ppp objects

MRT_LRT_NETWORK_PPP

summary(MRT_LRT_Network_ppp)
Planar point pattern:  171 points
Average intensity 2.153565e-07 points per square unit

Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units

Window: rectangle = [6138.31, 45254.86] x [27555.06, 47854.2] units
                    (39120 x 20300 units)
Window area = 794032000 square units

LISTINGS_2019_PPP

summary(Listings_2019_ppp)
Planar point pattern:  8293 points
Average intensity 9.345289e-06 points per square unit

*Pattern contains duplicated points*

Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units

Window: rectangle = [7215.57, 44098.31] x [25166.35, 49226.35] units
                    (36880 x 24060 units)
Window area = 887399000 square units

LISTINGS_2021_PPP

summary(Listings_2021_ppp)
Planar point pattern:  4252 points
Average intensity 5.131408e-06 points per square unit

*Pattern contains duplicated points*

Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units

Window: rectangle = [7406.99, 43337.89] x [25330, 48391.55] units
                    (35930 x 23060 units)
Window area = 828622000 square units

HOTELS_PPP

summary(Hotels_ppp)
Planar point pattern:  422 points
Average intensity 5.58414e-07 points per square unit

*Pattern contains duplicated points*

Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units

Window: rectangle = [5939.24, 45334.18] x [25379.44, 44562.4] units
                    (39390 x 19180 units)
Window area = 755712000 square units

TOURISM_PPP

summary(Tourism_ppp)
Planar point pattern:  106 points
Average intensity 1.328016e-07 points per square unit

*Pattern contains duplicated points*

Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units

Window: rectangle = [11380.23, 43659.54] x [22869.34, 47596.73] units
                    (32280 x 24730 units)
Window area = 798183000 square units

The summary of the above data shows that the following ppp pbjects have duplicated values which willlbe handled in the next section.

LISTINGS_2019_PPP, LISTINGS_2021_PPP, HOTELS_PPP and TOURISM_PPP

5.3 REMOVING DUPLICATE POINTS USING JITTERING FUNCTION

This section covers the steps taken to handle the duplicated values in the below ppp objects. The best solution to avoid deleting useful information is jittering, which will add a small perturbation to the duplicate points so that they do not occupy the exact same space

Listings_2019_ppp_jit <- rjitter(Listings_2019_ppp, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)
Listings_2021_ppp_jit <- rjitter(Listings_2021_ppp, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)
Hotels_ppp_jit <- rjitter(Hotels_ppp, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)
Tourism_ppp_jit <- rjitter(Tourism_ppp, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)

Checking if there are any duplicated values

LISTINGS_2019_PPP_JIT

any(duplicated(Listings_2019_ppp_jit))
[1] FALSE

LISTINGS_2021_PPP_JIT

any(duplicated(Listings_2021_ppp_jit))
[1] FALSE

HOTELS_PPP_JIT

any(duplicated(Hotels_ppp_jit))
[1] FALSE

TOURISM_PPP_JIT

any(duplicated(Tourism_ppp_jit))
[1] FALSE

There are no duplicated values and hence we can move on to the next crucial step which is creating the owin object

5.4 CREATING OWIN OBJECT

When analysing spatial point patterns, it is a good practice to confine the analysis with a geographical area like Singapore boundary. In spatstat, an object called owin is specially designed to represent this polygonal region.

sg_owin <- as(sg_sp, "owin")
plot(sg_owin)

summary(sg_owin)
Window: polygonal boundary
61 separate polygons (1 hole)
                  vertices         area relative.area
polygon 1               38  1.56140e+04      2.09e-05
polygon 2              735  4.69093e+06      6.27e-03
polygon 3               49  1.66986e+04      2.23e-05
polygon 4               76  3.12332e+05      4.17e-04
polygon 5             5141  6.36179e+08      8.50e-01
polygon 6               42  5.58317e+04      7.46e-05
polygon 7               67  1.31354e+06      1.75e-03
polygon 8               15  4.46420e+03      5.96e-06
polygon 9               14  5.46674e+03      7.30e-06
polygon 10              37  5.26194e+03      7.03e-06
polygon 11              53  3.44003e+04      4.59e-05
polygon 12              74  5.82234e+04      7.78e-05
polygon 13              69  5.63134e+04      7.52e-05
polygon 14             143  1.45139e+05      1.94e-04
polygon 15             165  3.38736e+05      4.52e-04
polygon 16             130  9.40465e+04      1.26e-04
polygon 17              19  1.80977e+03      2.42e-06
polygon 18              16  2.01046e+03      2.69e-06
polygon 19              93  4.30642e+05      5.75e-04
polygon 20              90  4.15092e+05      5.54e-04
polygon 21             721  1.92795e+06      2.57e-03
polygon 22             330  1.11896e+06      1.49e-03
polygon 23             115  9.28394e+05      1.24e-03
polygon 24              37  1.01705e+04      1.36e-05
polygon 25              25  1.66227e+04      2.22e-05
polygon 26              10  2.14507e+03      2.86e-06
polygon 27             190  2.02489e+05      2.70e-04
polygon 28             175  9.25904e+05      1.24e-03
polygon 29            1990  9.99217e+06      1.33e-02
polygon 30 (hole)        3 -1.06765e+00     -1.43e-09
polygon 31              38  2.42492e+04      3.24e-05
polygon 32              24  6.35239e+03      8.48e-06
polygon 33              53  6.35791e+05      8.49e-04
polygon 34              41  1.60161e+04      2.14e-05
polygon 35              22  2.54368e+03      3.40e-06
polygon 36              30  1.08382e+04      1.45e-05
polygon 37             327  2.16921e+06      2.90e-03
polygon 38             111  6.62927e+05      8.85e-04
polygon 39              90  1.15991e+05      1.55e-04
polygon 40              98  6.26829e+04      8.37e-05
polygon 41             415  3.25384e+06      4.35e-03
polygon 42             222  1.51142e+06      2.02e-03
polygon 43             107  6.33039e+05      8.45e-04
polygon 44               7  2.48299e+03      3.32e-06
polygon 45              17  3.28303e+04      4.38e-05
polygon 46              26  8.34758e+03      1.11e-05
polygon 47             177  4.67446e+05      6.24e-04
polygon 48              16  3.19460e+03      4.27e-06
polygon 49              15  4.87296e+03      6.51e-06
polygon 50              66  1.61841e+04      2.16e-05
polygon 51             149  5.63430e+06      7.53e-03
polygon 52             609  2.62570e+07      3.51e-02
polygon 53               8  7.82256e+03      1.04e-05
polygon 54             976  2.33447e+07      3.12e-02
polygon 55              55  8.25379e+04      1.10e-04
polygon 56             976  2.33447e+07      3.12e-02
polygon 57              61  3.33449e+05      4.45e-04
polygon 58               6  1.68410e+04      2.25e-05
polygon 59               4  9.45963e+03      1.26e-05
polygon 60              46  6.99702e+05      9.35e-04
polygon 61              13  7.00873e+04      9.36e-05
enclosing rectangle: [2663.93, 56047.79] x [16357.98, 50244.03] units
                     (53380 x 33890 units)
Window area = 748741000 square units
Fraction of frame area: 0.414

5.5 COMBINING POINT EVENTS OBJECT AND OWIN OBJECT

This is the last step of this entire data wrangling process of combining geospatial and aspatial data, which is to extract the relevant events that are located within Singapore.

MRT_LRT_network_ppp_sg = MRT_LRT_Network_ppp[sg_owin]
Listings_2019_ppp_sg = Listings_2019_ppp_jit[sg_owin]
Listings_2021_ppp_sg = Listings_2021_ppp_jit[sg_owin]
Hotels_ppp_sg = Hotels_ppp_jit[sg_owin]
Tourism_ppp_sg = Tourism_ppp_jit[sg_owin]

The output object above combined both the point and polygon feature in one ppp object class and it is good practice to visualise the combined data.

plot(MRT_LRT_network_ppp_sg)

par(mfrow=c(1,2))
plot(Listings_2019_ppp_sg)
plot(Listings_2021_ppp_sg)

plot(Hotels_ppp_sg)

plot(Tourism_ppp_sg)

Now we are all set for the performing the actual analysis!

6.0 [SECTION A] AIRBNB DISTRIBUTION ANALYSIS IN 2019

This section A covers the following two sets of analysis to determine how the distribution of Airbnb listings in Singapore is affected by location factors of MRTs, tourist attractions and hotels

6.1 [SECTION A] EXPLORATORY SPATIAL DATA ANALYSIS: KERNEL DENSITY MAPS

This section covers the steps taken to derive kernel density maps of Airbnb listings, hotels, MRT services, and tourist attractions.

6.1.1 RESCALLING KDE VALUES

The first step is to rescale and convert the unit of measurement from meter to kilometer, this step will ensure a better visualisation for comprehension

MRT_LRT_network_ppp_sg_km <- rescale(MRT_LRT_network_ppp_sg, 1000, 'km')
Listings_2019_ppp_sg_km <- rescale(Listings_2019_ppp_sg, 1000, 'km')
Listings_2021_ppp_sg_km <- rescale(Listings_2021_ppp_sg, 1000, 'km')
Hotels_ppp_sg_km <- rescale(Hotels_ppp_sg, 1000, 'km')
Tourism_ppp_sg_km <- rescale(Tourism_ppp_sg, 1000, 'km')

6.1.2 COMPUTING KERNEL DENSITY ESTIMATION

This section covers the steps taken to compute the Kernel Density estimation, there are many factors to consider and that will be detailed below with the reason

kde_MRT_LRT_network_sg_bw <- density(MRT_LRT_network_ppp_sg_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_listings_2019_sg_bw <- density(Listings_2019_ppp_sg_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_hotels_sg_bw <- density(Hotels_ppp_sg_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_tourism_sg_bw <- density(Tourism_ppp_sg_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")

6.1.3 PLOTTING KERNEL DENSITY MAPS

AIRBNB LISTINGS IN JUNE 2019

plot(kde_listings_2019_sg_bw)

It can be seen that most of the listings are clustered in the central region closer to the financial and business district where we have majority of our main attractions.

SINGAPORE MRT NETWORK

plot(kde_MRT_LRT_network_sg_bw)

It can be seen that the MRT stations are also mostly clustered around the central region where we have the business district, this is where we have many interchanges as well such as Dhoby Gaut, City Hall etc. There is another cluster in the north-east region which is probably because of the Punggol and Seng Kang LRT stations and the same explanation could also be applied to the cluster in the western part of Singapore where the bukit panjang LRT line is located.

HOTELS AROUND SNGAPORE

plot(kde_hotels_sg_bw)

As expected, the hotels are also clustered in the central region as per convenience of all travellers (business, tourist etc). This looks very similar to KDE map of Airbnb Listings, which makes me wonder if majority of the Airbnb listings are not only by local residents offering their houses but also smaller boutique hotels using Airbnb as a platform to reach out to the potential cutomers.

SINGAPORE TOURIST ATTRACTIONS

plot(kde_tourism_sg_bw)

I guess it does make sense that most of our tourist attractions like heritage sites, shopping districts and other attractions are all clustered in the central region

6.1.4 CONVERTING KDE OUTPUT INTO GRID OBJECT

gridded_kde_MRT_LRT_network_sg_bw <- as.SpatialGridDataFrame.im(kde_MRT_LRT_network_sg_bw)
gridded_kde_listings_2019_sg_bw <- as.SpatialGridDataFrame.im(kde_listings_2019_sg_bw)
gridded_kde_hotels_sg_bw <- as.SpatialGridDataFrame.im(kde_hotels_sg_bw)
gridded_kde_tourism_sg_bw <- as.SpatialGridDataFrame.im(kde_tourism_sg_bw)

Plotting the results:

AIRBNB LISTINGS IN 2019
spplot(gridded_kde_listings_2019_sg_bw)

SINGAPORE MRT NETWORK

spplot(gridded_kde_MRT_LRT_network_sg_bw)

HOTELS AROUND SNGAPORE

plot(gridded_kde_hotels_sg_bw)

SINGAPORE TOURIST ATTRACTIONS

plot(gridded_kde_tourism_sg_bw)

6.1.5 CONVERTING GRIDDED OUTPUT INTO RASTER

kde_MRT_LRT_network_sg_bw_raster <- raster(gridded_kde_MRT_LRT_network_sg_bw)
projection(kde_MRT_LRT_network_sg_bw_raster) <- CRS("+init=EPSG:3414")

kde_listings_2019_sg_bw_raster <- raster(gridded_kde_listings_2019_sg_bw)
projection(kde_listings_2019_sg_bw_raster) <- CRS("+init=EPSG:3414")

kde_hotels_sg_bw_raster <- raster(gridded_kde_hotels_sg_bw)
projection(kde_hotels_sg_bw_raster) <- CRS("+init=EPSG:3414")

kde_tourism_sg_bw <- raster(gridded_kde_tourism_sg_bw)
projection(kde_tourism_sg_bw) <- CRS("+init=EPSG:3414")

6.1.5 DISPLAYING KERNEL DENSITY MAPS ON OPENSTREETMAP

tmap_mode("view")

tm_shape(kde_listings_2019_sg_bw_raster) + 
  tm_raster("v", title = "Airbnb listings June 2019", alpha = 0.7, palette = "Reds") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE) +

tm_shape(kde_MRT_LRT_network_sg_bw_raster) + 
  tm_raster("v", title = "MRT Network", alpha = 0.7, palette = "Blues") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE) +
  
tm_shape(kde_hotels_sg_bw_raster) + 
  tm_raster("v", title = "Hotels", alpha = 0.7, palette = "Greens") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE) +
  
tm_shape(kde_tourism_sg_bw) + 
  tm_raster("v", title = "Tourist Attractions", alpha = 0.7, palette = "Purples") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
tmap_mode("plot")

ADVANTAGES OF KERNEL DENSITY OVER POINT MAP

OBSERVATIONS

It can be seen from the above Kernel Density maps that Airbnb listings, Tourist Attractions as well as Hotels seem to be clustered mostly around the central region, it might be more worth while to focus only on the central region

6.1.6 CREATING CENTRAL REGION OWIN OBJECT

In the following code chunk, we will be creating the Central region Owin from the mpsz_sf data object

Central_region_sf = mpsz_sf[mpsz_sf$REGION_N == "CENTRAL REGION",]
Central_region <- as_Spatial(Central_region_sf)
Central_region_SP = as(Central_region, "SpatialPolygons")
Central_region_owin <- as(Central_region_SP, "owin")
plot(Central_region_owin)

6.1.7 COMBINING POINT EVENTS OBJECT AND CENTRAL REGION OWIN OBJECT

MRT_LRT_network_ppp_CR = MRT_LRT_Network_ppp[Central_region_owin]
Listings_2019_ppp_CR = Listings_2019_ppp_jit[Central_region_owin]
Listings_2021_ppp_CR = Listings_2021_ppp_jit[Central_region_owin]
Hotels_ppp_CR = Hotels_ppp_jit[Central_region_owin]
Tourism_ppp_CR = Tourism_ppp_jit[Central_region_owin]

The output object above combined both the point and polygon feature in one ppp object class and it is good practice to visualise the combined data.

plot(MRT_LRT_network_ppp_CR)

par(mfrow=c(1,2))
plot(Listings_2019_ppp_CR)
plot(Listings_2021_ppp_CR)

plot(Hotels_ppp_CR)

plot(Tourism_ppp_CR)

6.1.8 RESCALLING KDE VALUES FOR CENTRAL REGION

MRT_LRT_network_ppp_CR_km <- rescale(MRT_LRT_network_ppp_CR, 1000, 'km')
Listings_2019_ppp_CR_km <- rescale(Listings_2019_ppp_CR, 1000, 'km')
Listings_2021_ppp_CR_km <- rescale(Listings_2021_ppp_CR, 1000, 'km')
Hotels_ppp_CR_km <- rescale(Hotels_ppp_CR, 1000, 'km')
Tourism_ppp_CR_km <- rescale(Tourism_ppp_CR, 1000, 'km')

6.1.9 COMPUTING KERNEL DENSITY ESTIMATION FOR CENTRAL REGION

kde_MRT_LRT_network_CR_bw <- density(MRT_LRT_network_ppp_CR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_listings_2019_CR_bw <- density(Listings_2019_ppp_CR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_hotels_CR_bw <- density(Hotels_ppp_CR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_tourism_CR_bw <- density(Tourism_ppp_CR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")

PLOTTING KERNEL DENSITY MAPS FOR CENTRAL REGION:

AIRBNB LISTINGS IN JUNE 2019

plot(kde_listings_2019_CR_bw)

SINGAPORE MRT NETWORK

plot(kde_MRT_LRT_network_CR_bw)

HOTELS AROUND SNGAPORE

plot(kde_hotels_CR_bw)

SINGAPORE TOURIST ATTRACTIONS

plot(kde_tourism_CR_bw)

Based on the above central region Kernel density maps, it can be seen that indeed Airbnb listings, MRT stations, hotels and tourist attractions are all mostly located within Central region of Singapore.

6.2 [SECTION A] SECOND-ORDER SPATIAL POINT PATTERN ANALYSIS

This section covers the steps taken to perform Second-order Spatial Point Patterns Analysis to determine if there is any impact of chosen factors such as Hotel distribution, MRT network and Tourist attraction on Airbnb listings. In the earlier section, we have identified that Airbnb Listings are mostly clustered in the central region and therefore the focus of this part of the analysis will also be on central region.

For the purpose of this analysis, will be applying the Second-order Multi-type Point Patterns Analysis using Cross L-Function

6.2.1 SECOND-ORDER SPATIAL POINT PATTERN ANALYSIS [Airbnb listings & Hotels]

CREATING NEW COMBINED PPP OBJECT

This new combined ppp object is created from Airbnblistings and Hotels ppp objects

Combined_A_H_ppp <- superimpose(Airbnblistings2019 = Listings_2019_ppp_CR,
                                Hotelsdist = Hotels_ppp_CR)

MULTI-TYPE POINT PATTERNS ANALYSIS

Combined_A_H_Lcross <- Lcross(Combined_A_H_ppp, i="Airbnblistings2019", j="Hotelsdist", correction='border')
plot(Combined_A_H_Lcross, . -r ~ r, 
     xlab = "distance(m)", 
     xlim=c(0, 500))

PERFORMING CSR ON CROSS L-FUNCTION

The hypothesis and test are as follows:

Ho = The distribution of Airbnb listings 2019 and Hotels in the central region are spatially independent.

H1= The distribution of Airbnb listings 2019 and Hotels in the central region are NOT at spatially independent.

The null hypothesis will be rejected if p-value is smaller than alpha value of 0.001 (i.e. at 99.9% confident interval).

In order to perform the CSR test, the envelope() of spatstat package will be used

Combined_A_H_Lcross.csr <- envelope(Combined_A_H_ppp, Lcross, i="Airbnblistings2019", j="Hotelsdist", correction='border', nsim=999)
Generating 999 simulations of CSR  ...
1, 2, 3, ......10 [etd 31:28] .........20 [etd 28:30] .........
30 [etd 27:42] .........40 [etd 27:08] .........50 [etd 26:33] ........
.60 [etd 26:03] .........70 [etd 25:50] .........80 [etd 25:36] .......
..90 [etd 25:11] .........100 [etd 24:54] .........110 [etd 24:38] ......
...120 [etd 24:17] .........130 [etd 24:01] .........140 [etd 23:55] .....
....150 [etd 23:41] .........160 [etd 23:21] .........170 [etd 23:00] ....
.....180 [etd 22:42] .........190 [etd 22:26] .........200 [etd 22:08] ...
......210 [etd 21:49] .........220 [etd 21:32] .........230 [etd 21:15] ..
.......240 [etd 21:01] .........250 [etd 20:43] .........260 [etd 20:25] .
........270 [etd 20:08] .........280 [etd 20:00] .........290
 [etd 19:42] .........300 [etd 19:26] .........310 [etd 19:09] .........
320 [etd 18:56] .........330 [etd 18:38] .........340 [etd 18:24] ........
.350 [etd 18:22] .........360 [etd 18:09] .........370 [etd 17:51] .......
..380 [etd 17:34] .........390 [etd 17:16] .........400 [etd 16:59] ......
...410 [etd 16:41] .........420 [etd 16:24] .........430 [etd 16:08] .....
....440 [etd 15:50] .........450 [etd 15:34] .........460 [etd 15:22] ....
.....470 [etd 15:08] .........480 [etd 14:50] .........490 [etd 14:33] ...
......500 [etd 14:16] .........510 [etd 13:58] .........520 [etd 13:41] ..
.......530 [etd 13:24] .........540 [etd 13:06] .........550 [etd 12:49] .
........560 [etd 12:31] .........570 [etd 12:14] .........580
 [etd 11:57] .........590 [etd 11:40] .........600 [etd 11:23] .........
610 [etd 11:05] .........620 [etd 10:48] .........630 [etd 10:31] ........
.640 [etd 10:14] .........650 [etd 9:56] .........660 [etd 9:40] .......
..670 [etd 9:23] .........680 [etd 9:07] .........690 [etd 8:49] ......
...700 [etd 8:32] .........710 [etd 8:15] .........720 [etd 7:58] .....
....730 [etd 7:41] .........740 [etd 7:24] .........750 [etd 7:07] ....
.....760 [etd 6:50] .........770 [etd 6:32] .........780 [etd 6:15] ...
......790 [etd 5:58] .........800 [etd 5:41] .........810 [etd 5:24] ..
.......820 [etd 5:07] .........830 [etd 4:49] .........840 [etd 4:33] .
........850 [etd 4:16] .........860 [etd 3:58] .........870
 [etd 3:41] .........880 [etd 3:24] .........890 [etd 3:07] .........
900 [etd 2:50] .........910 [etd 2:33] .........920 [etd 2:16] ........
.930 [etd 1:58] .........940 [etd 1:41] .........950 [etd 1:24] .......
..960 [etd 1:07] .........970 [etd 50 sec] .........980 [etd 33 sec] ......
...990 [etd 15 sec] ........ 999.

Done.
plot(Combined_A_H_Lcross.csr, . -r ~ r, xlab="distance(m)", xlim=c(0,500))

OBERVATIONS: * The black line is above the red line and beyond the upper confidence envelop, hence the null hypothesis is rejected at 99.9% confidence interval. * The distribution of Airbnb listings 2019 and Hotels in the central region are not spatially independent.

6.2.2 SECOND-ORDER SPATIAL POINT PATTERN ANALYSIS [Airbnb listings & Tourist Attractions]

CREATING NEW COMBINED PPP OBJECT

This new combined ppp object is created from Airbnblistings and Tourism ppp objects

Combined_A_T_ppp <- superimpose(Airbnblistings2019 = Listings_2019_ppp_CR,
                                TouristAttractions = Tourism_ppp_CR)

MULTI-TYPE POINT PATTERNS ANALYSIS

Combined_A_T_Lcross <- Lcross(Combined_A_T_ppp, i="Airbnblistings2019", j="TouristAttractions", correction='border')
plot(Combined_A_T_Lcross, . -r ~ r, 
     xlab = "distance(m)", 
     xlim=c(0, 500))

PERFORMING CSR ON CROSS L-FUNCTION

The hypothesis and test are as follows:

Ho = The distribution of Airbnb listings 2019 and Tourist Attractions in the central region are spatially independent.

H1= The distribution of Airbnb listings 2019 and Tourist Attractions in the central region are NOT at spatially independent.

The null hypothesis will be rejected if p-value is smaller than alpha value of 0.001 (i.e. at 99.9% confident interval).

In order to perform the CSR test, the envelope() of spatstat package will be used

Combined_A_T_Lcross.csr <- envelope(Combined_A_T_ppp, Lcross, i="Airbnblistings2019", j="TouristAttractions", correction='border', nsim=999)
Generating 999 simulations of CSR  ...
1, 2, 3, ......10 [etd 29:12] .........20 [etd 27:44] .........
30 [etd 26:54] .........40 [etd 26:20] .........50 [etd 25:42] ........
.60 [etd 25:55] .........70 [etd 25:25] .........80 [etd 25:01] .......
..90 [etd 24:34] .........100 [etd 24:15] .........110 [etd 23:57] ......
...120 [etd 23:36] .........130 [etd 23:20] .........140 [etd 23:04] .....
....150 [etd 22:48] .........160 [etd 22:30] .........170 [etd 22:11] ....
.....180 [etd 21:59] .........190 [etd 21:45] .........200 [etd 21:28] ...
......210 [etd 21:14] .........220 [etd 20:57] .........230 [etd 20:42] ..
.......240 [etd 20:25] .........250 [etd 20:08] .........260 [etd 19:50] .
........270 [etd 19:35] .........280 [etd 19:19] .........290
 [etd 19:02] .........300 [etd 18:45] .........310 [etd 18:31] .........
320 [etd 18:14] .........330 [etd 17:57] .........340 [etd 17:41] ........
.350 [etd 17:26] .........360 [etd 17:10] .........370 [etd 16:54] .......
..380 [etd 16:41] .........390 [etd 16:29] .........400 [etd 16:12] ......
...410 [etd 15:56] .........420 [etd 15:44] .........430 [etd 15:30] .....
....440 [etd 15:12] .........450 [etd 14:55] .........460 [etd 14:38] ....
.....470 [etd 14:21] .........480 [etd 14:04] .........490 [etd 13:47] ...
......500 [etd 13:31] .........510 [etd 13:15] .........520 [etd 12:59] ..
.......530 [etd 12:42] .........540 [etd 12:25] .........550 [etd 12:09] .
........560 [etd 11:53] .........570 [etd 11:36] .........580
 [etd 11:20] .........590 [etd 11:03] .........600 [etd 10:47] .........
610 [etd 10:30] .........620 [etd 10:13] .........630 [etd 9:57] ........
.640 [etd 9:41] .........650 [etd 9:24] .........660 [etd 9:08] .......
..670 [etd 8:51] .........680 [etd 8:35] .........690 [etd 8:19] ......
...700 [etd 8:03] .........710 [etd 7:47] .........720 [etd 7:31] .....
....730 [etd 7:15] .........740 [etd 6:59] .........750 [etd 6:43] ....
.....760 [etd 6:27] .........770 [etd 6:11] .........780 [etd 5:54] ...
......790 [etd 5:38] .........800 [etd 5:22] .........810 [etd 5:06] ..
.......820 [etd 4:50] .........830 [etd 4:33] .........840 [etd 4:17] .
........850 [etd 4:01] .........860 [etd 3:45] .........870
 [etd 3:29] .........880 [etd 3:13] .........890 [etd 2:56] .........
900 [etd 2:40] .........910 [etd 2:24] .........920 [etd 2:08] ........
.930 [etd 1:52] .........940 [etd 1:36] .........950 [etd 1:20] .......
..960 [etd 1:03] .........970 [etd 47 sec] .........980 [etd 31 sec] ......
...990 [etd 15 sec] ........ 999.

Done.
plot(Combined_A_T_Lcross.csr, . -r ~ r, xlab="distance(m)", xlim=c(0,500))

OBERVATIONS:

6.2.3 SECOND-ORDER SPATIAL POINT PATTERN ANALYSIS [Airbnb listings & MRT NETWORK]

CREATING NEW COMBINED PPP OBJECT

This new combined ppp object is created from Airbnblistings and Tourism ppp objects

Combined_A_M_ppp <- superimpose(Airbnblistings2019 = Listings_2019_ppp_CR,
                                MRTNetwork = MRT_LRT_network_ppp_CR)

MULTI-TYPE POINT PATTERNS ANALYSIS

Combined_A_M_Lcross <- Lcross(Combined_A_M_ppp, i="Airbnblistings2019", j="MRTNetwork", correction='border')
plot(Combined_A_M_Lcross, . -r ~ r, 
     xlab = "distance(m)", 
     xlim=c(0, 500))

PERFORMING CSR ON CROSS L-FUNCTION

The hypothesis and test are as follows:

Ho = The distribution of Airbnb listings 2019 and MRT Network in the central region are spatially independent.

H1= The distribution of Airbnb listings 2019 and MRT Network in the central region are NOT at spatially independent.

The null hypothesis will be rejected if p-value is smaller than alpha value of 0.001 (i.e. at 99.9% confident interval).

In order to perform the CSR test, the envelope() of spatstat package will be used

Combined_A_M_Lcross.csr <- envelope(Combined_A_M_ppp, Lcross, i="Airbnblistings2019", j="MRTNetwork", correction='border', nsim=999)
Generating 999 simulations of CSR  ...
1, 2, 3, ......10 [etd 58:02] .........20 [etd 42:19] .........
30 [etd 35:49] .........40 [etd 33:12] .........50 [etd 31:06] ........
.60 [etd 29:59] .........70 [etd 28:53] .........80 [etd 28:24] .......
..90 [etd 27:34] .........100 [etd 26:47] .........110 [etd 26:14] ......
...120 [etd 25:41] .........130 [etd 25:21] .........140 [etd 24:51] .....
....150 [etd 24:21] .........160 [etd 23:59] .........170 [etd 23:33] ....
.....180 [etd 23:12] .........190 [etd 22:48] .........200 [etd 22:25] ...
......210 [etd 22:09] .........220 [etd 21:47] .........230 [etd 21:26] ..
.......240 [etd 21:07] .........250 [etd 20:48] .........260 [etd 20:28] .
........270 [etd 20:08] .........280 [etd 19:48] .........290
 [etd 19:31] .........300 [etd 19:12] .........310 [etd 18:53] .........
320 [etd 18:34] .........330 [etd 18:16] .........340 [etd 17:57] ........
.350 [etd 17:38] .........360 [etd 17:20] .........370 [etd 17:05] .......
..380 [etd 16:48] .........390 [etd 16:30] .........400 [etd 16:13] ......
...410 [etd 15:55] .........420 [etd 15:38] .........430 [etd 15:21] .....
....440 [etd 15:04] .........450 [etd 14:46] .........460 [etd 14:31] ....
.....470 [etd 14:14] .........480 [etd 13:57] .........490 [etd 13:40] ...
......500 [etd 13:24] .........510 [etd 13:07] .........520 [etd 13:01] ..
.......530 [etd 13:00] .........540 [etd 13:00] .........550 [etd 12:51] .
........560 [etd 12:35] .........570 [etd 12:16] .........580
 [etd 11:58] .........590 [etd 11:41] .........600 [etd 11:23] .........
610 [etd 11:05] .........620 [etd 10:48] .........630 [etd 10:31] ........
.640 [etd 10:13] .........650 [etd 9:56] .........660 [etd 9:38] .......
..670 [etd 9:21] .........680 [etd 9:04] .........690 [etd 8:46] ......
...700 [etd 8:29] .........710 [etd 8:12] .........720 [etd 7:55] .....
....730 [etd 7:37] .........740 [etd 7:20] .........750 [etd 7:03] ....
.....760 [etd 6:46] .........770 [etd 6:28] .........780 [etd 6:11] ...
......790 [etd 5:55] .........800 [etd 5:38] .........810 [etd 5:21] ..
.......820 [etd 5:03] .........830 [etd 4:46] .........840 [etd 4:29] .
........850 [etd 4:14] .........860 [etd 3:56] .........870
 [etd 3:39] .........880 [etd 3:22] .........890 [etd 3:05] .........
900 [etd 2:48] .........910 [etd 2:31] .........920 [etd 2:14] ........
.930 [etd 1:57] .........940 [etd 1:40] .........950 [etd 1:23] .......
..960 [etd 1:06] .........970 [etd 49 sec] .........980 [etd 32 sec] ......
...990 [etd 15 sec] ........ 999.

Done.
plot(Combined_A_M_Lcross.csr, . -r ~ r, xlab="distance(m)", xlim=c(0,500))

OBERVATIONS:

7.0 [Section B] IMPACT OF COVID-19

This section B covers the following two sets of analysis to determine What is the impact of COVID-19 on Airbnb business in Singapore (comparing Airbnb listings data on June 2019 and June 2021)

7.1 [SECTION B] EXPLORATORY SPATIAL DATA ANALYSIS: KERNEL DENSITY MAPS]

This section covers the steps taken to derive kernel density maps of Airbnb listings by room type as of June 2019 and June 2021

It is always best practice to visualize your data first to increase our understanding

AIRBNB LISTINGS JUNE 2019

tmap_mode("view")
tm_shape(Listings_2019_sf) +
   tm_dots(col = 'room_type', size = 0.02, title = "Room Type")
tm_shape(mpsz) +
  tm_borders(alpha = 0.5) +
tm_shape(Listings_2019_sf) +
  tm_dots(col = 'room_type', 
          size = 0.5) +
tm_facets(by="room_type")

OBSERVATIONS * There were definitely more Private room listings island-wide, followed by Entire home/Apt listings and finally Shared room listings. * Shared room8 listings appear to be more concentrated in the central region where as Private room listings appear to be more equally distributed island-wide and Entire home/Apt appear to be concentrated mostly in the residential neighbourhoods of Singapore.

AIRBNB LISTINGS JUNE 2021

tmap_mode("view")
tm_shape(Listings_2021_sf) +
   tm_dots(col = 'room_type', size = 0.02, title = "Room Type")
tmap_mode("plot")
tm_shape(mpsz) +
  tm_borders(alpha = 0.5) +
tm_shape(Listings_2021_sf) +
  tm_dots(col = 'room_type', 
          size = 0.5) +
tm_facets(by="room_type")

OBSERVATIONS * There is an additional category called Hotel Room in the June 2021 Airbnb listings * There were definitely more Private room listings island-wide, followed by Entire home/Apt listings and finally Shared room listings. * Shared room8 listings appear to be more concentrated in the central region where as Private room listings appear to be more equally distributed island-wide and Entire home/Apt appear to be concentrated mostly in the residential neighborhoods of Singapore.

7.1.1 PRE-PROCESSING AIRBNB LISTINGS FOR JUNE 2019 AND JUNE 2021

EXTRACTING EACH ROOM TYPE FROM THE DATA FRAME

Listings_2019_SF_PR <- Listings_2019_sf[Listings_2019_sf$room_type == "Private room",]
Listings_2019_SF_EH <- Listings_2019_sf[Listings_2019_sf$room_type == "Entire home/apt",]
Listings_2019_SF_SR <- Listings_2019_sf[Listings_2019_sf$room_type == "Shared room",]

Listings_2021_SF_PR <- Listings_2021_sf[Listings_2021_sf$room_type == "Private room",]
Listings_2021_SF_EH <- Listings_2021_sf[Listings_2021_sf$room_type == "Entire home/apt",]
Listings_2021_SF_SR <- Listings_2021_sf[Listings_2021_sf$room_type == "Shared room",]
Listings_2021_SF_HR <- Listings_2021_sf[Listings_2021_sf$room_type == "Hotel room",]

CONVERTING SF DATA FRAMES TO SP’S SPATIAL* CLASS

Listings_2019_PR <- as_Spatial(Listings_2019_SF_PR)
Listings_2019_EH <- as_Spatial(Listings_2019_SF_EH)
Listings_2019_SR <- as_Spatial(Listings_2019_SF_SR)

Listings_2021_PR <- as_Spatial(Listings_2021_SF_PR)
Listings_2021_EH <- as_Spatial(Listings_2021_SF_EH)
Listings_2021_SR <- as_Spatial(Listings_2021_SF_SR)
Listings_2021_HR <- as_Spatial(Listings_2021_SF_HR)

CONVERTING SPATIAL* CLASS INTO GENERIC SP FORMAT

Listings_2019_SP_PR <- as(Listings_2019_PR, "SpatialPoints")
Listings_2019_SP_EH <- as(Listings_2019_EH, "SpatialPoints")
Listings_2019_SP_SR <- as(Listings_2019_SR, "SpatialPoints")

Listings_2021_SP_PR <- as(Listings_2021_PR, "SpatialPoints")
Listings_2021_SP_EH <- as(Listings_2021_EH, "SpatialPoints")
Listings_2021_SP_SR <- as(Listings_2021_SR, "SpatialPoints")
Listings_2021_SP_HR <- as(Listings_2021_HR, "SpatialPoints")

CONVERTING GENERIC SP FORMAT INTO SPATSTAT’S PPP FORMAT

Listings_2019_PPP_PR <- as(Listings_2019_SP_PR, "ppp")
Listings_2019_PPP_EH <- as(Listings_2019_SP_EH, "ppp")
Listings_2019_PPP_SR <- as(Listings_2019_SP_SR, "ppp")

Listings_2021_PPP_PR <- as(Listings_2021_SP_PR, "ppp")
Listings_2021_PPP_EH <- as(Listings_2021_SP_EH, "ppp")
Listings_2021_PPP_SR <- as(Listings_2021_SP_SR, "ppp")
Listings_2021_PPP_HR <- as(Listings_2021_SP_HR, "ppp")

HANDLING DUPLICATED POINTS

any(duplicated(Listings_2019_PPP_PR)) 
[1] FALSE
any(duplicated(Listings_2019_PPP_EH)) 
[1] TRUE
any(duplicated(Listings_2019_PPP_SR)) 
[1] TRUE
any(duplicated(Listings_2021_PPP_PR)) 
[1] TRUE
any(duplicated(Listings_2021_PPP_EH)) 
[1] TRUE
any(duplicated(Listings_2021_PPP_SR)) 
[1] TRUE
any(duplicated(Listings_2021_PPP_HR)) 
[1] TRUE

Therefore, all of the baove except for Listings_2019_PPP_PR have duplicated values and need to be handled

Listings_2019_PPP_Jit_PR <- rjitter(Listings_2019_PPP_PR, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)
Listings_2019_PPP_Jit_EH <- rjitter(Listings_2019_PPP_EH, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)
Listings_2019_PPP_Jit_SR <- rjitter(Listings_2019_PPP_SR, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)

Listings_2021_PPP_Jit_PR <- rjitter(Listings_2021_PPP_PR, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)
Listings_2021_PPP_Jit_EH <- rjitter(Listings_2021_PPP_EH, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)
Listings_2021_PPP_Jit_SR <- rjitter(Listings_2021_PPP_SR, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)
Listings_2021_PPP_Jit_HR <- rjitter(Listings_2021_PPP_HR, 
                             retry=TRUE, 
                             nsim=1, 
                             drop=TRUE)

COMBINING POINT EVENT OBJECTS AND OWIN OBJECT

Listings_2019_PPP_SG_PR = Listings_2019_PPP_Jit_PR[sg_owin]
Listings_2019_PPP_SG_EH = Listings_2019_PPP_Jit_EH[sg_owin]
Listings_2019_PPP_SG_SR = Listings_2019_PPP_Jit_SR[sg_owin]

Listings_2021_PPP_SG_PR = Listings_2021_PPP_Jit_PR[sg_owin]
Listings_2021_PPP_SG_EH = Listings_2021_PPP_Jit_EH[sg_owin]
Listings_2021_PPP_SG_SR = Listings_2021_PPP_Jit_SR[sg_owin]
Listings_2021_PPP_SG_HR = Listings_2021_PPP_Jit_HR[sg_owin]

RESCALLING KDE VALUES FOR CENTRAL REGION

Listings_2019_PPP_SG_PR_km <- rescale(Listings_2019_PPP_SG_PR, 1000, 'km')
Listings_2019_PPP_SG_EH_km <- rescale(Listings_2019_PPP_SG_EH, 1000, 'km')
Listings_2019_PPP_SG_SR_km <- rescale(Listings_2019_PPP_SG_SR, 1000, 'km')

Listings_2021_PPP_SG_PR_km <- rescale(Listings_2021_PPP_SG_PR, 1000, 'km')
Listings_2021_PPP_SG_EH_km <- rescale(Listings_2021_PPP_SG_EH, 1000, 'km')
Listings_2021_PPP_SG_SR_km <- rescale(Listings_2021_PPP_SG_SR, 1000, 'km')
Listings_2021_PPP_SG_HR_km <- rescale(Listings_2021_PPP_SG_HR, 1000, 'km')

7.1.2 COMPUTING KERNEL DENSITY ESTIMATION

This section covers the steps taken to compute the Kernel Density estimation, the following settings are used

kde_Listings_2019_SG_PR <- density(Listings_2019_PPP_SG_PR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_Listings_2019_SG_EH <- density(Listings_2019_PPP_SG_EH_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_Listings_2019_SG_SR <- density(Listings_2019_PPP_SG_SR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")

kde_Listings_2021_SG_PR <- density(Listings_2021_PPP_SG_PR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_Listings_2021_SG_EH <- density(Listings_2021_PPP_SG_EH_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_Listings_2021_SG_SR <- density(Listings_2021_PPP_SG_SR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")
kde_Listings_2021_SG_HR <- density(Listings_2021_PPP_SG_HR_km,
                                   sigma=bw.diggle,
                                   edge=TRUE,
                                   kernel="gaussian")

PLOTTING KERNEL DENSITY MAPS - JUNE 2019 LISTINGS

Private Rooms

plot(kde_Listings_2019_SG_PR)

Entire Appartment

plot(kde_Listings_2019_SG_EH)

Shared Rooms

plot(kde_Listings_2019_SG_SR)

PLOTTING KERNEL DENSITY MAPS - JUNE 2021 LISTINGS

Private Rooms
plot(kde_Listings_2021_SG_PR)

Entire Appartment

plot(kde_Listings_2021_SG_EH)

Shared Rooms

plot(kde_Listings_2021_SG_SR)

Hotel Rooms

plot(kde_Listings_2021_SG_HR)

7.1.3 PRE-PROCESSING FOR PLOTTING ON OPENSTREETMAPS

CONVERTING KDE OUTPUT INTO GRID OBJECT

gridded_kde_Listings_2019_SG_PR <- as.SpatialGridDataFrame.im(kde_Listings_2019_SG_PR)
gridded_kde_Listings_2019_SG_EH <- as.SpatialGridDataFrame.im(kde_Listings_2019_SG_EH)
gridded_kde_Listings_2019_SG_SR <- as.SpatialGridDataFrame.im(kde_Listings_2019_SG_SR)

gridded_kde_Listings_2021_SG_PR <- as.SpatialGridDataFrame.im(kde_Listings_2021_SG_PR)
gridded_kde_Listings_2021_SG_EH <- as.SpatialGridDataFrame.im(kde_Listings_2021_SG_EH)
gridded_kde_Listings_2021_SG_SR <- as.SpatialGridDataFrame.im(kde_Listings_2021_SG_SR)
gridded_kde_Listings_2021_SG_HR <- as.SpatialGridDataFrame.im(kde_Listings_2021_SG_HR)

CONVERTING GRIDDED OUTPUT INTO RASTER

kde_Listings_2019_SG_PR_raster <- raster(gridded_kde_Listings_2019_SG_PR)
projection(kde_Listings_2019_SG_PR_raster) <- CRS("+init=EPSG:3414")

kde_Listings_2019_SG_EH_raster <- raster(gridded_kde_Listings_2019_SG_EH)
projection(kde_Listings_2019_SG_EH_raster) <- CRS("+init=EPSG:3414")

kde_Listings_2019_SG_SR_raster <- raster(gridded_kde_Listings_2019_SG_SR)
projection(kde_Listings_2019_SG_SR_raster) <- CRS("+init=EPSG:3414")

kde_Listings_2021_SG_PR_raster <- raster(gridded_kde_Listings_2021_SG_PR)
projection(kde_Listings_2021_SG_PR_raster) <- CRS("+init=EPSG:3414")

kde_Listings_2021_SG_EH_raster <- raster(gridded_kde_Listings_2021_SG_EH)
projection(kde_Listings_2021_SG_PR_raster) <- CRS("+init=EPSG:3414")

kde_Listings_2021_SG_SR_raster <- raster(gridded_kde_Listings_2021_SG_SR)
projection(kde_Listings_2021_SG_PR_raster) <- CRS("+init=EPSG:3414")

kde_Listings_2021_SG_HR_raster <- raster(gridded_kde_Listings_2021_SG_HR)
projection(kde_Listings_2021_SG_PR_raster) <- CRS("+init=EPSG:3414")

DISPLAYING KERNEL DENSITY MAPS ON OPENSTREETMAP

PRIVATE ROOM - JUNE 2019 VS JUNE 2021

Listings_2019_SF_PR <- Listings_2019_sf[Listings_2019_sf$room_type == “Private room”,] Listings_2019_SF_EH <- Listings_2019_sf[Listings_2019_sf$room_type == “Entire home/apt”,] Listings_2019_SF_SR <- Listings_2019_sf[Listings_2019_sf$room_type == “Shared room”,]

Listings_2021_SF_PR <- Listings_2021_sf[Listings_2021_sf$room_type == “Private room”,] Listings_2021_SF_EH <- Listings_2021_sf[Listings_2021_sf$room_type == “Entire home/apt”,] Listings_2021_SF_SR <- Listings_2021_sf[Listings_2021_sf$room_type == “Shared room”,] Listings_2021_SF_HR

tm_shape(mpsz) +
  tm_borders(alpha = 0.5) +
tm_shape(Listings_2019_SF_PR ) +
  tm_dots(col = 'room_type', 
          size = 0.5, title = "June 2019", palette = "Reds") 
tm_shape(mpsz) +
  tm_borders(alpha = 0.5) +
tm_shape(Listings_2021_SF_PR ) +
  tm_dots(col = 'room_type', 
          size = 0.5, title = "June 2021")

tmap_mode("view")

tm_shape(kde_Listings_2019_SG_PR_raster) + 
  tm_raster("v", title = "Private Rooms June 2019", alpha = 0.7, palette = "Reds") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE) +

tm_shape(kde_Listings_2021_SG_PR_raster) + 
  tm_raster("v", title = "Private Rooms June 2021", alpha = 0.7, palette = "Blues") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE)

Observations: There are more private room listings in June 2019 as compared to June 2021

ENTIRE APARTMENT - JUNE 2019 VS JUNE 2021

tm_shape(mpsz) +
  tm_borders(alpha = 0.5) +
tm_shape(Listings_2019_SF_EH ) +
  tm_dots(col = 'room_type', 
          size = 0.5, title = "June 2019", palette = "Reds") 
tm_shape(mpsz) +
  tm_borders(alpha = 0.5) +
tm_shape(Listings_2021_SF_EH ) +
  tm_dots(col = 'room_type', 
          size = 0.5, title = "June 2021")
tmap_mode("view")

tm_shape(kde_Listings_2019_SG_EH_raster) + 
  tm_raster("v", title = "Entire Apartments June 2019", alpha = 0.7, palette = "Reds") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE) +

tm_shape(kde_Listings_2021_SG_EH_raster) + 
  tm_raster("v", title = "Entire Apartments June 2021", alpha = 0.7, palette = "Blues") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE)

Observations: There are more Entire Apartment listings in June 2019 as compared to June 2021

SHARED ROOM - JUNE 2019 VS JUNE 2021

tm_shape(mpsz) +
  tm_borders(alpha = 0.5) +
tm_shape(Listings_2019_SF_SR ) +
  tm_dots(col = 'room_type', 
          size = 0.5, title = "June 2019", palette = "Reds") 
tm_shape(mpsz) +
  tm_borders(alpha = 0.5) +
tm_shape(Listings_2021_SF_SR ) +
  tm_dots(col = 'room_type', 
          size = 0.5, title = "June 2021")
tmap_mode("view")

tm_shape(kde_Listings_2019_SG_SR_raster) + 
  tm_raster("v", title = "Shared room June 2019", alpha = 0.7, palette = "Reds") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE) +

tm_shape(kde_Listings_2021_SG_SR_raster) + 
  tm_raster("v", title = "Shared room June 2021", alpha = 0.7, palette = "Blues") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE)

HOTEL ROOM - JUNE 2021

tmap_mode("view")

tm_shape(kde_Listings_2021_SG_HR_raster) + 
  tm_raster("v", title = "Hotel room June 2021", alpha = 0.7, palette = "Blues") +
  tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
tmap_mode("plot")

7.2 [SECTION B] SECOND-ORDER SPATIAL POINT PATTERN ANALYSIS

This section covers the steps taken to perform Second-order Spatial Point Patterns Analysis to determine the impact of COVID-19 on Airbnb listings in June 2019 and June 2021. For the purpose of this analysis, will be applying the Second-order Multi-type Point Patterns Analysis using Cross L-Function

7.2.1 SECOND-ORDER SPATIAL POINT PATTERN ANALYSIS [PRIVATE ROOM VS ENTIRE APPARTMENT - JUNE 2019]

CREATING NEW COMBINED PPP OBJECT

This new combined ppp object is created from Airbnb listings for private rooms from June 2019 and June 2021

Combined_PR_EH_ppp <- superimpose(PR_2019 = Listings_2019_PPP_SG_PR,
                                  EH_2019 = Listings_2019_PPP_SG_EH)

MULTI-TYPE POINT PATTERNS ANALYSIS

Combined_PR_EH_Lcross_2019 <- Lcross(Combined_PR_EH_ppp, i="PR_2019", j="EH_2019", correction='border')
plot(Combined_PR_EH_Lcross_2019, . -r ~ r, 
     xlab = "distance(m)", 
     xlim=c(0, 500))

PERFORMING CSR ON CROSS L-FUNCTION

The hypothesis and test are as follows:

Ho = The distribution of private room listings in June 2019 and June 2021 are spatially independent.

H1= The distribution of private room listings in June 2019 and June 2021 are NOT spatially independent.

The null hypothesis will be rejected if p-value is smaller than alpha value of 0.001 (i.e. at 99.9% confident interval).

In order to perform the CSR test, the envelope() of spatstat package will be used

OBERVATIONS: